// 处理方法
import { keepDecimal, updateNumberValue } from "@/utils/index";
export function initWay(vm) {
  return {
    updatemodelParams(arr) {
      vm.modelParams = arr;
    },
    // 更新箭头和框体位置的方法
    updateArrowAndBorderPosition(object) {
      // console.log("updateArrowAndBorderPosition", object);
      const canvas = vm.canvas;
      // 获取对象的最新位置（中心点）
      const posX = object.get("left");
      const posY = object.get("top");
      // 获取对象的宽度和高度
      // const width = object.get("width");
      // const height = object.get("height");
      const width = object.getScaledWidth();
      const height = object.getScaledHeight();
      // 获取对象的旋转角度
      const angle = object.get("angle");
      // 查找对应的 allObjects 中的对象
      const obj = vm.allObjects.find((item) => item.fabricObject === object);
      if (obj) {
        if (obj.arrowObject) {
          vm.arrowcompute(obj, height, posX, posY, angle);
        }
        if (obj.borderObject) {
          obj.borderObject.set({
            left: posX,
            top: posY,
            angle: angle,
            visible: vm.isBorderVisible,
          });
        }
        canvas.requestRenderAll();
      }
    },
    updateAllObjectsconfigForm(formvalue) {
      vm.allObjects.forEach((item) => {
        if (item.allObjectsid === formvalue.allObjectsid) {
          item.configForm = formvalue;
        }
      });
    },
    // 箭头计算
    arrowcompute(obj, height, posX, posY, angle) {
      let that = vm;
      // const arrowOffset = (height * vm.rate) / 2 + 24;
      const arrowOffset = height / 2 + that.borderAndpadding; // height已经是缩放后的实际高度
      // 计算箭头的相对位置（相对于中心点）
      const relativeX = 0;
      const relativeY = arrowOffset;
      // 将相对位置转换为旋转后的绝对位置
      const rotatedX =
        relativeX * Math.cos((angle * Math.PI) / 180) -
        relativeY * Math.sin((angle * Math.PI) / 180);
      const rotatedY =
        relativeX * Math.sin((angle * Math.PI) / 180) +
        relativeY * Math.cos((angle * Math.PI) / 180);
      // 设置箭头的最终位置和角度
      const xx = posX + rotatedX;
      const yy = posY + rotatedY;
      obj.arrowObject.set({
        left: keepDecimal(xx, vm.dig, 1),
        top: keepDecimal(yy, vm.dig, 1),
        angle: keepDecimal(angle, vm.dig, 1),
      });
      obj.arrowObject.visible = vm.isArrowVisible; // 同步更新箭头可见性
    },
    // 构造fabric的Image对象方法
    constructionFabricImage(
      imgObj,
      left,
      top,
      scaleX,
      scaleY,
      angle,
      modelId,
      imageUrl
    ) {
      // 从对象池获取
      // 如果池中没有可用对象，创建新对象
      const fabricImg = new fabric.Image(imgObj, {
        left: left,
        top: top,
        originX: "center",
        originY: "center",
        scaleX: scaleX,
        scaleY: scaleY,
        selectable: true,
        lockScalingX: false,
        lockScalingY: false,
        angle: angle,
        modelId: modelId,
        originalSrc: imageUrl,
      });
      // console.log('constructionFabricImage - scaleX:', fabricImg.scaleX);
      // console.log('constructionFabricImage - scaleY:', fabricImg.scaleY);
      return fabricImg;
    },
    // 放置图片方法
    async wayPlaceImage(event, placeType) {
      try {
        let imgtarget, name, targetObj, configForm;
        switch (placeType) {
          case "selectedImg":
            imgtarget = vm.selectedImg;
            // 确保imageUrl是字符串
            if (
              !imgtarget?.imageUrl ||
              typeof imgtarget.imageUrl !== "string"
            ) {
              throw new Error("无效的图片URL");
            }
            name = `${vm.choseImg.modelName}-${vm.allObjects.length}`;
            targetObj = {};
            break;
          case "selectedPosition":
            // console.log(vm.selectedPosition, "vm.selectedPosition");
            imgtarget = vm.positionImg;
            // 确保imageUrl是字符串
            if (
              !imgtarget?.imageUrl ||
              typeof imgtarget.imageUrl !== "string"
            ) {
              throw new Error("无效的图片URL");
            }
            name = vm.selectedPosition?.posName ?? "未知业务名称";
            targetObj = vm.selectedPosition;
            const configvalue = vm.selectedPosition?.config ?? "";
            if (configvalue.length > 0) {
              configForm = JSON.parse(configvalue);
            } else {
              configForm = {};
            }
            break;
          default:
            break;
        }
        console.log(imgtarget, "imgtarget");
        const imgObj = await vm.wayLoadImage(imgtarget.imageUrl);
        // 获取底图的初始缩放比例
        const initialZoom = vm.initialZoom;
        const originalWidth = imgtarget.w;
        const originalHeight = imgtarget.h;
        // // 计算图片的显示宽度和高度，基于原始尺寸和一个固定的比例
        const displayWidth = originalWidth * vm.rate; // 调整这个值来控制图片的初始大小
        const displayHeight = originalHeight * vm.rate;
        // 转换坐标到画布实际位置
        const pointer = vm.canvas.getPointer(event);
        const centerX = keepDecimal(pointer.x, vm.dig, 1);
        const centerY = keepDecimal(pointer.y, vm.dig, 1);
        const fabricImg = vm.constructionFabricImage(
          imgObj,
          centerX,
          centerY,
          displayWidth / originalWidth,
          displayHeight / originalHeight,
          0,
          imgtarget.modelId,
          imgtarget.imageUrl
        );
        // 添加对象到画布
        vm.canvas.add(fabricImg);
        // fabricImg.moveTo(3); // 3表示在箭头(2)之上
        // 设置选中状态
        vm.canvas.setActiveObject(fabricImg);
        // 始终创建箭头对象，但根据isArrowVisible设置其可见性
        const arrow = vm.wayArrowAdd(centerX, centerY, displayHeight);
        arrow.visible = vm.isArrowVisible; // 根据isArrowVisible设置箭头可见性
        const border = vm.wayBorderAdd(
          centerX,
          centerY,
          displayWidth,
          displayHeight
        );
        border.visible = vm.isBorderVisible; // 根据isBorderVisible设置边框可见性
        // 生成文字
        const text = vm.wayTextAdd(centerX, centerY, placeType);
        text.visible = vm.isTextVisible; // 根据isTextVisible设置文字可见性
        // 保存到 allObjects
        let buildObj = {
          allObjectsid: Date.now(), // 添加唯一的 id
          text: name,
          x: centerX,
          y: centerY,
          // width: imgObj.width * scaleFactor,
          // height: imgObj.height * scaleFactor,
          width: displayWidth,
          height: displayHeight,
          angle: 0,
          fabricObject: fabricImg,
          textObject: text, // 保存文字对象引用
          arrowObject: arrow, // 保存箭头对象引用
          borderObject: border, // 保存边框对象引用
          targetObj: targetObj, // 保存业务对象
          imgtarget: imgtarget, //
          posId:
            placeType === "selectedPosition"
              ? vm.selectedPosition.posId
              : undefined,
          posNo:
            placeType === "selectedPosition"
              ? vm.selectedPosition.posNo
              : Math.floor(Date.now() / 1000) + "", // 初始化 posNo
          type:
            placeType === "selectedPosition"
              ? vm.selectedPosition.type
              : "Shelf",
          configFormOld:
            placeType === "selectedPosition" ? configForm : undefined,
          configForm: placeType === "selectedPosition" ? configForm : undefined,
          tags: [], // 标签列表
        };

        vm.allObjects.push(buildObj);
        // 更新choseObj
        vm.choseObj = vm.allObjects[vm.allObjects.length - 1];
        vm.show3 = true; // 显示选中对象区域
        // 主动触发选中逻辑，确保页面上显示红色边框
        vm.handleObjectSelected({ selected: [fabricImg] });
        // 重置选择状态
        if (placeType === "selectedPosition") {
          vm.deleteBusinessItem();
          vm.selectedPosition = null;
        } else if (placeType === "selectedImg") {
          vm.selectedImg = null;
          vm.choseImg = {};
        }
        vm.canvas.defaultCursor = "default";
        // 画布渲染
        vm.updateAllObjectsCoords();
        vm.canvas.requestRenderAll();
      } catch (error) {
        console.error("图片加载失败1:", error);
      }
    },
    // 文字添加方法
    wayTextAdd(centerX, centerY, type, posName) {
      let name;
      switch (type) {
        case "selectedImg":
          name = `${vm.choseImg.modelName}-${vm.allObjects.length}`;
          break;
        case "selectedPosition":
          name = vm.selectedPosition?.posName ?? "未知业务名称";
          break;
        default:
          break;
      }
      // 反显赋值
      if (posName) {
        name = posName;
      }
      const text = new fabric.IText(name, {
        left: centerX,
        top: centerY,
        fontSize: 20,
        fill: "black",
        originX: "center",
        originY: "center",
        selectable: false,
        evented: false,
        textBaseline: "alphabetic",
        fontFamily: "Arial", // 显式设置字体
      });
      // 添加文字到画布
      vm.canvas.add(text);
      // 设置文字始终在图片上方
      text.bringToFront();
      // text.moveTo(4); // 4表示在图片(3)之上
      return text;
    },
    // 箭头添加方法
    wayArrowAdd(centerX, centerY, imgHeight) {
      let that = vm;
      // 计算箭头的偏移量为图片高度的一半
      const arrowOffset = imgHeight / 2 + that.borderAndpadding;
      // 创建箭头对象，使用iconfont的字体
      const arrow = new fabric.IText("\ue600", {
        // 这里是iconfont箭头的Unicode编码
        left: centerX,
        top: centerY + arrowOffset, // 箭头位置在底边中心点上
        fontSize: 24,
        fill: "black",
        originX: "center",
        originY: "center",
        selectable: false,
        evented: false,
        fontFamily: "iconfont", // 设置字体为iconfont
        textBaseline: "alphabetic",
      });
      // 添加箭头到画布
      vm.canvas.add(arrow);
      // 设置箭头始终在图片上方
      arrow.bringToFront();
      // arrow.moveTo(2); // 2表示在边框(1)之上
      return arrow;
    },
    // 边框添加方法
    wayBorderAdd(centerX, centerY, width, height, angle = 0) {
      let that = vm;
      // 创建边框对象，距离图片20px
      const border = new fabric.Rect({
        width: width + that.borderAndpadding, // 图片宽度+20px每边
        height: height + that.borderAndpadding, // 图片高度+20px每边
        left: centerX,
        top: centerY,
        originX: "center",
        originY: "center",
        stroke: "red",
        strokeWidth: 2,
        angle: angle, // 设置旋转角度
        fill: "transparent",
        selectable: false,
        evented: false,
        visible: vm.isBorderVisible,
        // Fabric 5.x 需要显式设置strokeUniform避免缩放影响边框宽度
        strokeUniform: true,
        // 添加阴影效果增强可见性
        shadow: new fabric.Shadow({
          color: "rgba(255,0,0,0.3)",
          blur: 5,
          offsetX: 0,
          offsetY: 0,
        }),
      });

      // 添加边框到画布
      vm.canvas.add(border);
      // 设置边框层级在底图之上
      // border.moveTo(1); // 1表示在背景(0)之上
      border.bringToFront();
      return border;
    },
    // 图片加载方法
    wayLoadImage(url) {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.onload = () => resolve(img);
        img.onerror = (error) => {
          console.error("图片加载失败2:", error);
          reject(error);
        };
        img.src = url;
      });
    },
    // 辅助方法：更新所有对象的坐标
    updateAllObjectsCoords() {
      vm.canvas.forEachObject((obj) => {
        // if (obj.isDirty) {
        // 只有脏对象才更新
        obj.setCoords();
        // obj.isDirty = false;
        // }
      });
    },
    // 辅助方法：检查功能键
    isFunctionalKeyPressed(event) {
      return event.ctrlKey || event.shiftKey || event.altKey || event.metaKey;
    },
    // 校验 posNo 是否有重复
    checkPosNoDuplication() {
      const posNoList = vm.allObjects.map((obj) => obj.posNo.toString());
      const uniquePosNoList = [...new Set(posNoList)];
      console.log(posNoList, uniquePosNoList);
      if (posNoList.length !== uniquePosNoList.length) {
        return false;
      } else {
        return true;
      }
    },
    // 更新对象属性
    updateObjProperty(obj, property, value) {
      console.log(obj, property, value);
      if (
        property === "w" ||
        property === "h" ||
        property === "x" ||
        property === "y" ||
        property === "angle" ||
        property === "posNo"
      ) {
        if (property === "posNo") {
          // 确保 posNo 是正整数
          const parsedValue = parseInt(value);
          if (!isNaN(parsedValue) && parsedValue > 0) {
            obj[property] = parsedValue;
          } else {
            return; // 无效输入，不更新
          }
        } else if (property === "w" || property === "h") {
          // 处理宽度/高度修改
          value = updateNumberValue(value);
          // 获取图片元素
          // const imgElement = obj.fabricObject._element;
          // console.log(imgElement, "imgElement");
          // 获取原始尺寸（从模型数据）
          const originalWidth = obj.imgtarget.w;
          const originalHeight = obj.imgtarget.h;
          if (property === "w") {
            // 计算缩放比例并应用
            const scaleX = value / originalWidth;
            obj.fabricObject.set({
              scaleX: scaleX,
              // scaleX: 1,
              // width: value, // 更新显示宽度
            });
            // imgElement.width = value;
            obj.width = value; // 更新数据模型-
            // 更新边框宽度
            if (obj.borderObject) {
              obj.borderObject.set({
                // scaleX: scaleX,
                // scaleX: 1,
                width: value + vm.borderAndpadding,
              });
            }
          } else {
            // 处理高度修改
            const scaleY = value / originalHeight;
            obj.fabricObject.set({
              scaleY: scaleY,
              // scaleY: 1,
              // height: value,
            });
            // 更新图片实际高度
            // imgElement.height = value;
            obj.height = value;
            // 更新边框高度
            if (obj.borderObject) {
              obj.borderObject.set({
                // scaleY: scaleY,
                // scaleY: 1,
                height: value + vm.borderAndpadding,
              });
            }
          }
          // 更新箭头位置
          if (obj.arrowObject || obj.borderObject) {
            vm.updateArrowAndBorderPosition(obj.fabricObject);
          }
          // 更新边框位置
          // if (obj.borderObject) {
          //   obj.borderObject.set({
          //     left: obj.fabricObject.left,
          //     top: obj.fabricObject.top,
          //     angle: obj.fabricObject.angle,
          //   });
          // }
          obj.fabricObject.setCoords();
          vm.canvas.requestRenderAll();
        } else {
          value = updateNumberValue(value);
          obj[property] = value;
          if (obj.fabricObject) {
            if (property === "x") {
              obj.fabricObject.set("left", value);
            } else if (property === "y") {
              obj.fabricObject.set("top", value);
            } else {
              obj.fabricObject.set(property, value);
            }
          }
          // 如果有文字对象，更新其位置和可见性
          if (obj.textObject) {
            if (property === "x") {
              obj.textObject.set("left", value);
            } else if (property === "y") {
              obj.textObject.set("top", value);
            } else {
              obj.textObject.set(property, value);
            }
            obj.textObject.visible = vm.isTextVisible; // 同步更新文字可见性
          }
          // 如果有箭头对象，更新其位置和可见性
          if (obj.arrowObject) {
            let posX, posY, angle, height;
            if (property === "x" || property === "y") {
              posX = obj.x;
              posY = obj.y;
              angle = obj.angle;
              height = obj.height;
            } else {
              posX = obj.x;
              posY = obj.y;
              angle = value;
              height = obj.height;
            }
            // 这里获取的高度是相对于底图的缩放比例，需要转换为画布实际高度
            vm.arrowcompute(obj, height / vm.rate, posX, posY, angle);
          }
          // 如果有边框对象，更新边框位置和角度
          if (obj.borderObject) {
            obj.borderObject.set({
              left: obj.x,
              top: obj.y,
              angle: obj.angle,
              visible: vm.isBorderVisible,
            });
          }
        }
      } else if (property === "tags") {
        obj[property] = value;
      }
      vm.updateAllObjectsCoords();
      vm.canvas.requestRenderAll();
    },
    // 更新对象文字
    updateObjText(obj) {
      if (obj.textObject) {
        obj.textObject.set("text", obj.text);
        vm.canvas.requestRenderAll();
      }
    },
  };
}
